package com.infindo.twitter;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.graphics.Color;
import android.net.Uri;

/*<user>
 <id>1401881</id>
 <name>Doug Williams</name>
 <screen_name>dougw</screen_name>
 <location>San Francisco, CA</location>
 <description>Twitter API Support. Internet, greed, users, dougw and opportunities are my passions.</description>
 <profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/59648642/avatar_normal.png</profile_image_url>
 <url>http://www.igudo.com</url>
 <protected>false</protected>
 <followers_count>1027</followers_count>
 <profile_background_color>9ae4e8</profile_background_color>
 <profile_text_color>000000</profile_text_color>
 <profile_link_color>0000ff</profile_link_color>
 <profile_sidebar_fill_color>e0ff92</profile_sidebar_fill_color>
 <profile_sidebar_border_color>87bc44</profile_sidebar_border_color>
 <friends_count>293</friends_count>
 <created_at>Sun Mar 18 06:42:26 +0000 2007</created_at>
 <favourites_count>0</favourites_count>
 <utc_offset>-18000</utc_offset>
 <time_zone>Eastern Time (US & Canada)</time_zone>
 <profile_background_image_url>http://s3.amazonaws.com/twitter_production/profile_background_images/2752608/twitter_bg_grass.jpg</profile_background_image_url>
 <profile_background_tile>false</profile_background_tile>
 <statuses_count>3390</statuses_count>
 <notifications>false</notifications>
 <following>false</following>
 <status>
 <created_at>Mon May 04 05:18:07 +0000 2009</created_at> 
 <id>1693356811</id> 
 <text>@prasanna are you using neo? How well does it scale?</text> 
 <source><a href="http://orangatame.com/products/twitterberry/">TwitterBerry</a></source> 
 <truncated>false</truncated> 
 <in_reply_to_status_id /> 
 <in_reply_to_user_id>5626</in_reply_to_user_id> 
 <favorited>false</favorited> 
 <in_reply_to_screen_name>prasanna</in_reply_to_screen_name> 
 </status>
 </user>*/

public class UsersHandler extends DefaultHandler {

	public enum UsersHandlerType {
		NONE, ID, SCREENNAME
	}

	@SuppressWarnings("unused")
	private static final String XML_USERS = "users";
	private static final String XML_USER = "user";
	private static final String XML_ID = "id";
	private static final String XML_NAME = "name";
	private static final String XML_SCREEN_NAME = "screen_name";
	private static final String XML_LOCATION = "location";
	private static final String XML_DESCRIPTION = "description";
	private static final String XML_PROFILE_IMAGE_URL = "profile_image_url";
	private static final String XML_URL = "url";
	private static final String XML_PROTECTED = "protected";
	private static final String XML_FOLLOWERS_COUNT = "followers_count";
	private static final String XML_PROFILE_BACKGROUND_COLOR = "profile_background_color";
	private static final String XML_PROFILE_TEXT_COLOR = "profile_text_color";
	private static final String XML_PROFILE_LINK_COLOR = "profile_link_color";
	private static final String XML_PROFILE_SIDEBAR_FILL_COLOR = "profile_sidebar_fill_color";
	private static final String XML_PROFILE_SIDEBAR_BORDER_COLOR = "profile_sidebar_border_color";
	private static final String XML_FRIENDS_COUNT = "friends_count";
	private static final String XML_CREATED_AT = "created_at";
	private static final String XML_FAVOURITES_COUNT = "favourites_count";
	private static final String XML_UTC_OFFSET = "utc_offset";
	private static final String XML_TIME_ZONE = "time_zone";
	private static final String XML_PROFILE_BACKGROUND_IMAGE_URL = "profile_background_image_url";
	private static final String XML_PROFILE_BACKGROUND_TILE = "profile";
	private static final String XML_STATUSES_COUNT = "statuses_count";
	private static final String XML_NOTIFICATIONS = "notifications";
	private static final String XML_FOLLOWING = "following";
	private static final String XML_STATUS = "status";

	private UsersHandlerType handlerType;
	private HashMap<String, User> users;
	private User currentUser;

	private String ElementName = "";
	private Boolean isTweet = false;

	public UsersHandler(UsersHandlerType type) {
		super();

		this.handlerType = type;
	}

	@Override
	public void startDocument() throws SAXException {
		users = new HashMap<String, User>();
	}

	@Override
	public void endDocument() throws SAXException {
		// Nothing to do
	}

	@Override
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		ElementName = localName;

		if (localName == XML_USER) {
			currentUser = new User();
		} else if (localName == XML_STATUS) {
			isTweet = true;
		}

	}

	@Override
	public void endElement(String namespaceURI, String localName, String qName)
			throws SAXException {
		ElementName = "";

		if (localName == XML_USER) {
			if (handlerType == UsersHandlerType.ID) {
				users.put(Integer.toString(currentUser.getId()), currentUser);
			} else if (handlerType == UsersHandlerType.SCREENNAME) {
				users.put(currentUser.getScreenName(), currentUser);
			}
		} else if (localName == XML_STATUS) {
			isTweet = false;
		}
	}

	@Override
	public void characters(char ch[], int start, int length) {
		String data = new String(ch, start, length);

		if (isTweet && ElementName == XML_ID) {
			currentUser.setStatus(new Tweet(Integer.parseInt(data)));
		} else {
			SetValue(currentUser, ElementName, data);
		}
	}
	
	public User GetUser(Integer Id) {
		if (handlerType == UsersHandlerType.ID) {
			if (users.containsKey(Integer.toString(Id))) {
				return users.get(Integer.toString(Id));
			} else {
				return null;
			}
		} else if (handlerType == UsersHandlerType.SCREENNAME) {

			Collection<User> c = users.values();
			Iterator<User> itr = c.iterator();
			User usr;

			while (itr.hasNext()) {
				usr = itr.next();
				if (usr.getId() == Id) {
					return usr;
				}
			}
			return null;
		} else {
			return null;
		}
	}

	public User GetUser(String screenName) {
		if (handlerType == UsersHandlerType.SCREENNAME) {
			if (users.containsKey(screenName)) {
				return users.get(screenName);
			} else {
				return null;
			}
		} else if (handlerType == UsersHandlerType.ID) {

			Collection<User> c = users.values();
			Iterator<User> itr = c.iterator();
			User usr;

			while (itr.hasNext()) {
				usr = itr.next();
				if (usr.getScreenName() == screenName) {
					return usr;
				}
			}
			return null;
		} else {
			return null;
		}
	}
	
	public HashMap<String, User> GetUsers() {
		return users;
	}

	private void SetValue(User user, String name, String value) {
		if (name == XML_ID) {
			user.setId(Integer.parseInt(value));
		} else if (name == XML_NAME) {
			user.setName(value);
		} else if (name == XML_SCREEN_NAME) {
			user.setScreenName(value);
		} else if (name == XML_LOCATION) {
			user.setLocation(value);
		} else if (name == XML_DESCRIPTION) {
			user.setDescription(value);
		} else if (name == XML_PROFILE_IMAGE_URL) {
			user.setProfileImageUrl(Uri.parse(value));
		} else if (name == XML_URL) {
			user.setUrl(Uri.parse(value));
		} else if (name == XML_PROTECTED) {
			user.setProtected(Boolean.parseBoolean(value));
		} else if (name == XML_FOLLOWERS_COUNT) {
			user.setFollowersCount(Integer.parseInt(value));
		} else if (name == XML_PROFILE_BACKGROUND_COLOR) {
			user.setProfileBackgroundColor(Color.parseColor("#" + value));
		} else if (name == XML_PROFILE_TEXT_COLOR) {
			user.setProfileTextColor(Color.parseColor("#" + value));
		} else if (name == XML_PROFILE_LINK_COLOR) {
			user.setProfileLinkColor(Color.parseColor("#" + value));
		} else if (name == XML_PROFILE_SIDEBAR_FILL_COLOR) {
			user.setProfileSidebarFillColor(Color.parseColor("#" + value));
		} else if (name == XML_PROFILE_SIDEBAR_BORDER_COLOR) {
			user.setProfileSidebarBorderColor(Color.parseColor("#" + value));
		} else if (name == XML_FRIENDS_COUNT) {
			user.setFriendsCount(Integer.parseInt(value));
		} else if (name == XML_CREATED_AT) {
			try {
				DateFormat df = new SimpleDateFormat("E M d H:m:s Z S");
				user.setCreatedAt(df.parse(value));
			} catch (ParseException e) {
				user.setCreatedAt(null);
			}
		} else if (name == XML_FAVOURITES_COUNT) {
			user.setFavouritesCount(Integer.parseInt(value));
		} else if (name == XML_UTC_OFFSET) {
			user.setUtcOffset(Integer.parseInt(value));
		} else if (name == XML_TIME_ZONE) {
			user.setTimeZone(value);
		} else if (name == XML_PROFILE_BACKGROUND_IMAGE_URL) {
			user.setProfileBackgroundImageUrl(Uri.parse(value));
		} else if (name == XML_PROFILE_BACKGROUND_TILE) {
			user.setProfileBackgroundTile(Boolean.parseBoolean(value));
		} else if (name == XML_STATUSES_COUNT) {
			user.setStatusesCount(Integer.parseInt(value));
		} else if (name == XML_NOTIFICATIONS) {
			user.setNotifications(Boolean.parseBoolean(value));
		} else if (name == XML_FOLLOWING) {
			user.setFollowing(Boolean.parseBoolean(value));
		}
	}
}